# -*- coding: utf-8 -*-
import json
from sqlalchemy import Column,String,Integer,Text,Binary,Boolean,DateTime,Enum,Float
from adminApp.extensions import db
from datetime import datetime, date


class BaseModel(object):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    created = db.Column(db.DateTime, nullable=False, default=db.func.now())
    updated = db.Column(db.DateTime, onupdate=db.func.now())

    def single_to_dict(self, no_create_update=True):
        return {c.name: getattr(self, c.name) for c in self.__table__.columns if no_create_update and c.name not in ['created','updated']}

    def dobule_to_dict(self, no_create_update=True):
        result = {}
        for key in self.__mapper__.c.keys():
            if no_create_update and key in ['created', 'updated']:
                continue
            if getattr(self, key) is not None:
                result[key] = str(getattr(self, key))
            else:
                result[key] = getattr(self, key)
        return result

    def __init__(self, include_related=False, **items):
        if include_related:
            for key in items:
                if hasattr(self, key):
                    setattr(self, key, items[key])
        else:
            columns = {c.name:c.type for c in self.__table__.columns}
            for key in items:
                if hasattr(self, key) and key in columns.keys():
                    if isinstance(columns[key], (String,Text)) and not isinstance(items[key], str):
                        try:
                            setattr(self, key, json.dumps(items[key], indent=1))
                        except:
                            setattr(self, key, str(items[key]))
                    else:
                        setattr(self, key, items[key])

    def update_from_dict(self, include_related=False, **items):
        # 更新模型 从字典中加载更新的数据
        if include_related:
            for key in items:
                if hasattr(self, key):
                    setattr(self, key, items[key])
        else:
            columns = {c.name: c.type for c in self.__table__.columns}
            for key in items:
                if hasattr(self, key) and key in columns.keys():
                    if isinstance(columns[key], (String,Text)) and not isinstance(items[key], str):
                        # if isinstance(columns[key], (String, Text)) and not isinstance(items[key], (str, int, float, bool, datetime, date)):
                        try:
                            setattr(self, key, json.dumps(items[key], indent=1))
                        except:
                            setattr(self, key, str(items[key]))
                    else:
                        setattr(self, key, items[key])

    @classmethod
    def format_to_update_dict(cls, include_related=False, **items):
        # 适用与查询更新 批量更新 session.query(**).filter(**).update(dict())
        # 取 items 中可以使用的更新项目
        result = dict()

        if include_related:
            for key in items:
                if hasattr(cls, key):
                    result[key] = items[key]
        else:
            column_strs = [c.name for c in cls.__table__.columns]
            for key in items:
                if hasattr(cls, key) and key in column_strs:
                    # setattr(cls, key, items[key])
                    result[key] = items[key]
        return result

    def to_json(self):
        dicts = self.__dict__
        if "_sa_instance_state" in dicts:
            del dicts["_sa_instance_state"]
        return dicts
